import { Context, Next } from 'koa';
import { AppContext, UserType } from '@/types';
import { verifyToken } from '@/utils/jwt';
import User from '@/models/User.model';
import logger from '@/utils/logger';

/**
 * 认证中间件
 * 验证 JWT token 并将用户信息挂载到 ctx.state
 */
export default async function auth(ctx: Context, next: Next) {
  const appCtx = ctx as AppContext;

  // 从 Authorization 头获取 token
  const authHeader = ctx.get('Authorization');
  if (!authHeader || !authHeader.startsWith('Bearer ')) {
    ctx.throw(401, '未提供认证令牌');
  }

  const token = authHeader.slice(7); // 移除 'Bearer ' 前缀

  try {
    // 验证 token
    const payload = verifyToken(token);

    // 查询用户
    const user = await User.findByPk(payload.userId);

    if (!user) {
      ctx.throw(401, '用户不存在');
    }

    if (!user.isActive()) {
      ctx.throw(401, '用户已被禁用');
    }

    // 检查租户匹配（对于非超级管理员）
    if (user.type !== UserType.SUPER_ADMIN && appCtx.state.tenant) {
      if (user.tenantId !== appCtx.state.tenant.id) {
        ctx.throw(403, '无权访问此租户');
      }
    }

    // 将用户信息挂载到 ctx.state
    appCtx.state.user = {
      id: user.id,
      tenantId: user.tenantId,
      email: user.email,
      type: user.type as any,
      roleId: user.roleId,
    };

    logger.debug(`用户认证成功: ${user.email} (${user.id})`);
  } catch (error) {
    if (error instanceof Error) {
      if (error.message.includes('令牌') || error.message.includes('用户')) {
        throw error;
      }
    }
    logger.error('认证失败:', error);
    ctx.throw(401, '认证失败');
  }

  await next();
}

/**
 * 可选认证中间件
 * 尝试认证但不强制要求
 */
export async function optionalAuth(ctx: Context, next: Next) {
  try {
    await auth(ctx, next);
  } catch (error) {
    // 忽略认证错误，继续执行
    await next();
  }
}

